package org.hgvc.webapp.ets.spring.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import org.hgvc.webapp.ets.bo.Agent;
import org.hgvc.webapp.ets.bo.Agreement;
import org.hgvc.webapp.ets.bo.DocControl;
import org.hgvc.webapp.ets.bo.Guest;
import org.hgvc.webapp.ets.bo.Member;
import org.hgvc.webapp.ets.bo.Voucher;
import org.hgvc.webapp.ets.bo.VoucherEntry;
import org.hgvc.webapp.ets.bo.VoucherEntryDetail;
import org.hgvc.webapp.ets.constant.AdminConstant;
import org.hgvc.webapp.ets.constant.CommonConstant;
import org.hgvc.webapp.ets.jsf.beans.voucher.VoucherBean;
import org.hgvc.webapp.ets.spring.dao.AdminHbmDao;
import org.hgvc.webapp.ets.spring.dao.AgentHbmDao;
import org.hgvc.webapp.ets.spring.dao.VoucherHbmDao;
import org.jocsb.base.bo.Role;
import org.jocsb.base.bo.User;
import org.jocsb.base.comparator.GenericComparator;
import org.jocsb.base.exception.BaseException;
import org.jocsb.base.util.SpringUtils;


public class VoucherServiceImpl implements VoucherService{
	private VoucherHbmDao dao;
	private AdminHbmDao adminHbmDao;
	private AgentHbmDao agentDao;
	private AdminService adminService;
	private MasterSetupService masterSetupService;
	
	public void setDao(VoucherHbmDao dao) {
		this.dao = dao;
	}
	public void setAdminHbmDao(AdminHbmDao adminHbmDao) {
		this.adminHbmDao = adminHbmDao;
	}
	public void setAgentDao(AgentHbmDao agentDao) {
		this.agentDao = agentDao;
	}
	public void setAdminService(AdminService adminService) {
		this.adminService = adminService;
	}
	public void setMasterSetupService(MasterSetupService masterSetupService) {
		this.masterSetupService = masterSetupService;
	}
	
	public List<Voucher> getVoucherUnassignList()throws BaseException{
		List<Voucher> list = new ArrayList<Voucher>();
		
		try{
			list = dao.getVoucherUnassignList();
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{Voucher.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<Voucher> getVoucherAssignedListByAgent(Agent agent)throws BaseException{
		List<Voucher> list = new ArrayList<Voucher>();
		
		try{
			list = dao.getVoucherAssignedListByAgent(agent);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{Voucher.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<Voucher> getVoucherAssignedListByUser(User user)throws BaseException{
		List<Voucher> list = new ArrayList<Voucher>();
		
		try{
			list = dao.getVoucherAssignedListByUser(user);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{Voucher.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<Voucher> getVoucherAvailableListByUser(User user)throws BaseException{
		List<Voucher> list = new ArrayList<Voucher>();
		
		try{
			List<Voucher> allList = dao.getVoucherAssignedListByUser(user);
			HashSet allListHs=new HashSet(allList);
			List<Voucher> notAvalableList = dao.getVoucherListByAssignedVoucherEntryUser(user);
			allListHs.removeAll(notAvalableList);
			
			list=new ArrayList<Voucher>(allListHs);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{Voucher.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<Voucher> getVoucherListSellByUser(User user)throws BaseException{
		List<Voucher> list = new ArrayList<Voucher>();
		
		try{
			list = dao.getVoucherListByAssignedVoucherEntryUser(user);
			
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{Voucher.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<Agent> getAgentApprovedList()throws BaseException{
		List<Agent> list=new ArrayList<Agent>();
		try{
			list=agentDao.getAgentApprovedList();
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{Agent.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<User> getUserListByRole(Role role)throws BaseException{
		List<User> list=new ArrayList<User>();
		try{
			list=adminHbmDao.getUserByRole(role.getRoleId());
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{User.class.getSimpleName()}));
		}
		return list;
	}
	
	public String generateVoucher(Voucher voucherParam,Integer vouchersQty)throws BaseException{
		String ack="";
		try{
			DocControl docControl = this.masterSetupService.getDocControlByType(CommonConstant.DOC_TYPE_VOUCHER);
			String prefix=docControl==null?"":docControl.getPrefix();
			
			int noOfVouchers = vouchersQty==null?0:vouchersQty.intValue();
			String startVoucherNo="";
			String endVoucherNo="";
			String voucherNo="";
			for (int i=0;i<noOfVouchers;i++){
				voucherNo=adminService.getDocumentNo(CommonConstant.DOC_TYPE_VOUCHER);
				Voucher voucher=new Voucher();
				voucher.setVoucherNo(voucherNo);
				voucher.setVoucherNumber(Integer.parseInt(voucherNo.substring(prefix.length())));
				voucher.setAssignToAgent(voucherParam.getAssignToAgent());
				voucher.setAssignToHgvcUser(voucherParam.getAssignToHgvcUser());
				voucher.setCreatedBy(voucher.getCreatedBy());
				voucher.setEffectiveDate(voucherParam.getEffectiveDate());
				voucher.setExpiryDate(voucherParam.getExpiryDate());
				voucher.setIsDeleted(CommonConstant.NOT_DELETED);
				voucher.setNoOfNights(voucherParam.getNoOfNights());
				voucher.setNoOfPerson(voucherParam.getNoOfPerson());
				voucher.setProduct1(voucherParam.getProduct1());
				voucher.setProduct2(voucherParam.getProduct2().getPartnerProductId().length()<=0?null:voucherParam.getProduct2());
				voucher.setProduct3(voucherParam.getProduct3().getPartnerProductId().length()<=0?null:voucherParam.getProduct3());
				voucher.setProduct4(voucherParam.getProduct4().getPartnerProductId().length()<=0?null:voucherParam.getProduct4());
				voucher.setProduct5(voucherParam.getProduct5().getPartnerProductId().length()<=0?null:voucherParam.getProduct5());
				voucher.setCreatedDate(new Date());
				
				dao.save(voucher);
				if (i==0)
					startVoucherNo=voucherNo;
				else if (i==noOfVouchers-1)
					endVoucherNo=voucherNo;
			}
			ack=SpringUtils.getMessage("ack.voucher.generate", new Object[]{startVoucherNo,endVoucherNo});
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.generate.voucher", new Object[]{}));
		}
		return ack;
	}
	
	public void voucherAssignment(Agent agent,Voucher startVoucher,Voucher lastVoucher)throws BaseException{
		try{
			List<Voucher> voucherList=dao.getVoucherList(startVoucher, lastVoucher);
			for (Voucher voucher : voucherList){
				voucher.setAssignToAgent(agent);
				voucher.setModifiedDate(new Date());
				dao.update(voucher);
			}
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.voucher.assignment.agent", new Object[]{}));
		}
	}
	
	public void voucherAssignment(User hgvcUser,Voucher startVoucher,Voucher lastVoucher)throws BaseException{
		try{
			List<Voucher> voucherList=dao.getVoucherList(startVoucher, lastVoucher);
			for (Voucher voucher : voucherList){
				voucher.setAssignToHgvcUser(hgvcUser);
				voucher.setModifiedDate(new Date());
				dao.update(voucher);
			}
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.voucher.assignment.employee", new Object[]{}));
		}
	}
	
	public void voucherUnassignment(Agent agent,Voucher startVoucher,Voucher lastVoucher)throws BaseException{
		try{
			List<Voucher> voucherList=dao.getVoucherList(agent, startVoucher, lastVoucher);
			for (Voucher voucher : voucherList){
				voucher.setAssignToAgent(null);
				voucher.setModifiedDate(new Date());
				dao.update(voucher);
			}
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.voucher.unassignment.agent", new Object[]{}));
		}
	}
	
	public void voucherUnassignment(User hgvcUser,Voucher startVoucher,Voucher lastVoucher)throws BaseException{
		try{
			List<Voucher> voucherList=dao.getVoucherList(hgvcUser, startVoucher, lastVoucher);
			for (Voucher voucher : voucherList){
				voucher.setAssignToHgvcUser(null);
				voucher.setModifiedDate(new Date());
				dao.update(voucher);
			}
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.voucher.unassignment.agent", new Object[]{}));
		}
	}
	
	public List<VoucherBean> getVoucherReportList(String voucherNo,Date effectiveDate,Date expiryDate)throws BaseException{
		List<VoucherBean> list=new ArrayList<VoucherBean>();
		try{
			List<Voucher> voucherList=dao.getVoucherList(voucherNo, effectiveDate, expiryDate);
			
			for (Voucher voucher : voucherList){
				VoucherBean bean=new VoucherBean();
				bean.setVoucherNo(voucher.getVoucherNo());
				bean.setVoucherNumber(voucher.getVoucherNumber());
				bean.setCode(voucher.getProduct1().getCode());
				bean.setNoOfNights(voucher.getNoOfNights());
				bean.setNoOfPerson(voucher.getNoOfPerson());
				bean.setEffectiveDate(voucher.getEffectiveDate());
				bean.setExpiryDate(voucher.getExpiryDate());
				
				list.add(bean);
			}
			GenericComparator sorter=new GenericComparator(VoucherBean.class,"voucherNumber");
			sorter.setAscending(true);
			Collections.sort( list,  sorter  );
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{VoucherBean.class.getSimpleName()}));
		}
		return list;
	}
	
	public Guest getGuestByIcNo(String icNo)throws BaseException{
		Guest guest = null;
		try{
			guest=dao.getGuestByIcNo(icNo);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.get.object", new Object[]{Guest.class.getSimpleName()}));
		}
		return guest;
	}
	
	public VoucherEntry getVoucherEntryByAgreement(Agreement agreement)throws BaseException{
		VoucherEntry voucherEntry=null;
		try{
			voucherEntry=dao.getVoucherEntryByAgreement(agreement);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.get.object", new Object[]{VoucherEntry.class.getSimpleName()}));
		}
		return voucherEntry;
	}
	
	public VoucherEntry getVoucherEntryByProspect(Member prospect)throws BaseException{
		VoucherEntry voucherEntry=null;
		try{
			voucherEntry=dao.getVoucherEntryByProspect(prospect);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.get.object", new Object[]{VoucherEntry.class.getSimpleName()}));
		}
		return voucherEntry;
	}
	
	public VoucherEntry getVoucherEntryByGuest(Guest guestParam)throws BaseException{
		VoucherEntry voucherEntry=null;
		try{
			Guest guest=null;
			if (guestParam!=null){
				if (guestParam.getGuestId()==null)
				    guest = dao.getGuestByIcNo(guestParam.getIcNo());
				else
					guest=guestParam;
				voucherEntry=dao.getVoucherEntryByGuest(guest);	
			}
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.get.object", new Object[]{VoucherEntry.class.getSimpleName()}));
		}
		return voucherEntry;
	}
	
	public List<VoucherEntryDetail> getVoucherEntryDetailList(VoucherEntry voucherEntry)throws BaseException{
		List<VoucherEntryDetail> list=new ArrayList<VoucherEntryDetail>();
		try{
			list=dao.getVoucherEntryDetailList(voucherEntry);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{VoucherEntryDetail.class.getSimpleName()}));
		}
		return list;
	}
	
	public VoucherEntry saveVoucherEntry(String entryType,VoucherEntry voucherEntryParam,VoucherEntryDetail voucherEntryDetail)throws BaseException{
		VoucherEntry voucherEntry=null;
		try{
			Guest guest=null;
			//Prospect prospect=null;
			if (entryType.equalsIgnoreCase(AdminConstant.MEMBER))
				voucherEntry = dao.getVoucherEntryByAgreement(voucherEntryParam.getAgreement());
			else if (entryType.equalsIgnoreCase(AdminConstant.NON_MEMBER)){
				voucherEntry = dao.getVoucherEntryByProspect(voucherEntryParam.getProspect());
			}else if (entryType.equalsIgnoreCase(AdminConstant.GUEST)){
				guest = dao.getGuestByIcNo(voucherEntryParam.getGuest().getIcNo());
				if (guest==null){
					guest=new Guest();
					guest.setName(voucherEntryParam.getGuest().getName());
					guest.setIcNo(voucherEntryParam.getGuest().getIcNo());
					guest.setIsDeleted(CommonConstant.NOT_DELETED);
					guest.setCreatedDate(new Date());
					dao.save(guest);
				}else{
					guest.setName(voucherEntryParam.getGuest().getName());
					guest.setModifiedDate(new Date());
					dao.update(guest);
				}
				voucherEntry = dao.getVoucherEntryByGuest(guest);
			}
			
			if (voucherEntry==null){
				voucherEntry=voucherEntryParam;
				voucherEntry.setGuest(guest);
				voucherEntry.setProspect(voucherEntryParam.getProspect());
				voucherEntry.setAgreement(voucherEntryParam.getAgreement());
				dao.save(voucherEntry);
			}
			Voucher voucher=(Voucher) dao.getObject(Voucher.class, voucherEntryDetail.getVoucher().getVoucherId());
			voucherEntryDetail.setVoucher(voucher);
			voucherEntryDetail.setVoucherEntry(voucherEntry);
			voucherEntryDetail.setIssueDate(voucher.getCreatedDate());
			voucherEntryDetail.setCreatedDate(new Date());
			voucherEntryDetail.setStatus(AdminConstant.STATUS_PENDING);
			
			dao.save(voucherEntryDetail);
			
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.voucher.entry.update", new Object[]{entryType}));
		}
		return voucherEntry;
	}
	
	public void removeVoucherEntry(List<VoucherEntryDetail> deleteList)throws BaseException{
		try{
			for(VoucherEntryDetail voucherEntryDetail : deleteList){
				if (voucherEntryDetail.getStatus().equalsIgnoreCase(AdminConstant.STATUS_PENDING)){
					voucherEntryDetail.setModifiedDate(new Date());
					voucherEntryDetail.setIsDeleted(CommonConstant.IS_DELETED);
					dao.update(voucherEntryDetail);	
				}
			}
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{VoucherEntryDetail.class.getSimpleName()}));
		}
	}
	
	public List<VoucherBean> getComplimentaryAccommVoucherList(Voucher voucher)throws BaseException{
		List<VoucherBean> list=new ArrayList<VoucherBean>();
		try{
			VoucherBean bean=new VoucherBean();
			VoucherEntryDetail voucherEntryDetail=dao.getVoucherEntryDetailByVoucher(voucher);
			if (voucherEntryDetail!=null){
				if (voucherEntryDetail.getVoucherEntry().getAgreement()!=null){
					bean.setAgreementDate(voucherEntryDetail.getVoucherEntry().getAgreement().getAgreetmentDate());
					bean.setAgreementNo(voucherEntryDetail.getVoucherEntry().getAgreement().getAgreetmentNo());
					bean.setMemberSelect("X");
				}else{
					bean.setNonMemberSelect("X");
					if (voucherEntryDetail.getVoucherEntry().getGuest()!=null){
						bean.setIssueTo(voucherEntryDetail.getVoucherEntry().getGuest().getName());
						bean.setIcNo(voucherEntryDetail.getVoucherEntry().getGuest().getIcNo());
					}
					if (voucherEntryDetail.getVoucherEntry().getProspect()!=null){
						bean.setIssueTo(voucherEntryDetail.getVoucherEntry().getProspect().getName());
						bean.setIcNo(voucherEntryDetail.getVoucherEntry().getProspect().getMemberRegNo());
					}
				}
				if (voucherEntryDetail.getVoucher().getProduct1()!=null)
				   bean.setProductName1(voucherEntryDetail.getVoucher().getProduct1().getName());
				if (voucherEntryDetail.getVoucher().getProduct2()!=null)
					   bean.setProductName2(voucherEntryDetail.getVoucher().getProduct2().getName());
				if (voucherEntryDetail.getVoucher().getProduct3()!=null)
					   bean.setProductName3(voucherEntryDetail.getVoucher().getProduct3().getName());
				if (voucherEntryDetail.getVoucher().getProduct4()!=null)
					   bean.setProductName4(voucherEntryDetail.getVoucher().getProduct4().getName());
				if (voucherEntryDetail.getVoucher().getProduct5()!=null)
					   bean.setProductName5(voucherEntryDetail.getVoucher().getProduct5().getName());
				
				bean.setVoucherNo(voucherEntryDetail.getVoucher().getVoucherNo());
				bean.setEffectiveDate(voucherEntryDetail.getVoucher().getEffectiveDate());
				bean.setExpiryDate(voucherEntryDetail.getVoucher().getExpiryDate());
			}
			
			list.add(bean);
			
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{VoucherBean.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<VoucherEntryDetail> getVoucherEntryDetailList()throws BaseException{
		List<VoucherEntryDetail> list=new ArrayList<VoucherEntryDetail>();
		try{
			list=dao.getVoucherEntryDetailList();
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{VoucherEntryDetail.class.getSimpleName()}));
		}
		return list;
	}
	
	public List<VoucherEntryDetail> getVoucherEntryDetailAvailableList()throws BaseException{
		List<VoucherEntryDetail> list=new ArrayList<VoucherEntryDetail>();
		try{
			list=dao.getVoucherEntryDetailAvailableList();
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{VoucherEntryDetail.class.getSimpleName()}));
		}
		return list;
	}
}
